package com.zxy.study.ui.opengl;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

import com.zxy.study.R;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_LINEAR;
import static android.opengl.GLES20.GL_REPEAT;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
import static android.opengl.GLES20.GL_TEXTURE_WRAP_S;
import static android.opengl.GLES20.GL_TEXTURE_WRAP_T;
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
import static android.opengl.GLES20.glBindTexture;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGenTextures;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glTexParameteri;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.GLES20.glViewport;


/*
 *  @项目名：  study
 *  @包名：    com.zxy.study.ui.opengl
 *  @文件名:   XYRender
 *  @创建者:   zhangxy
 *  @创建时间:  2019/8/12 10:25
 *  @描述：    TODO
 */
public class XYRender implements GLSurfaceView.Renderer {
	private static final int POSITION_COUNT = 2;
	private static final int BYTE_PER_FLOAT = 4;
	private static final String U_COLOR = "u_Color";
	private static final String A_POSITION = "a_Position";

	private Context mContext;
	private FloatBuffer vertexData;
	private FloatBuffer textureData;
	private int programObjectId;

	private int uColorLocation;
	private int aPositionLocation;

	private int avPosition;
	private int afPosition;


	public XYRender(Context context) {
		mContext = context;

		//		float[] vertex = {-1f, 0f, 0f, -1f, 0f, 1f,
		//
		//			0f, 1f, 0f, -1f, 1f, 0f};

		float[] vertex = {-1f, -1f, 1f, -1f, -1f, 1f, 1f, 1f};

		vertexData = ByteBuffer.allocateDirect(vertex.length * BYTE_PER_FLOAT)
			.order(ByteOrder.nativeOrder())
			.asFloatBuffer()
			.put(vertex);
		vertexData.position(0);

		float[] textures = {0f, 1f, 1f, 1f, 0f, 0f, 1f, 0f};
		textureData = ByteBuffer.allocateDirect(textures.length * BYTE_PER_FLOAT)
			.order(ByteOrder.nativeOrder())
			.asFloatBuffer()
			.put(textures);
		textureData.position(0);
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		//		glClearColor(1.0f, 0, 0, 0);
		//
		//		String vertexShaderCode = TextResourceReader.readTextFileFromResource(mContext, R.raw.simple_vertex_shader);
		//		int vertexShaderId = ShaderHelper.compileVertexShader(vertexShaderCode);
		//
		//		String fragmentShaderCode = TextResourceReader.readTextFileFromResource(mContext, R.raw.simple_fragment_shader);
		//		int fragmentShaderId = ShaderHelper.compileFragmentShader(fragmentShaderCode);
		//
		//		programObjectId = ShaderHelper.linkProgram(vertexShaderId, fragmentShaderId);
		//		ShaderHelper.validateProgram(programObjectId);
		//
		//		glUseProgram(programObjectId);
		//
		//		uColorLocation = glGetUniformLocation(programObjectId, U_COLOR);
		//		aPositionLocation = glGetAttribLocation(programObjectId, A_POSITION);
		//
		//
		//		vertexData.position(0);
		//		glVertexAttribPointer(aPositionLocation, POSITION_COUNT, GL_FLOAT, false, 0, vertexData);
		//		glEnableVertexAttribArray(aPositionLocation);

		String vertexShaderCode = TextResourceReader.readTextFileFromResource(mContext, R.raw.vertex_texture_shader);
		String fragmentShaderCode = TextResourceReader.readTextFileFromResource(mContext, R.raw.fragment_texture_shader);
		programObjectId = ShaderHelper.createProgram(vertexShaderCode, fragmentShaderCode);

		if (programObjectId > 0) {

			avPosition = glGetAttribLocation(programObjectId, "av_Position");
			afPosition = glGetAttribLocation(programObjectId, "af_Position");

			int[] textureIds = new int[1];
			glGenTextures(1, textureIds, 0);

			if (textureIds[0] == 0) {
				return;
			}
			int textureId = textureIds[0];
			glBindTexture(GL_TEXTURE_2D, textureId);

			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

			Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.timg);
			if (bitmap == null) {
				return;
			}
			GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
			bitmap.recycle();
			bitmap = null;
		}
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		glViewport(0, 0, width, height);
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		glClear(GL_COLOR_BUFFER_BIT);
		glClearColor(1.0f,1.0f,1.0f,1.0f);

		//		glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);
		//		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

		glUseProgram(programObjectId);

		glEnableVertexAttribArray(avPosition);
		glVertexAttribPointer(avPosition, 2, GL_FLOAT, false, 8, vertexData);

		glEnableVertexAttribArray(afPosition);
		glVertexAttribPointer(afPosition, 2, GL_FLOAT, false, 8, textureData);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	}
}
